#ifndef CAT_AND_MOUSE_H_INCLUDED
#define CAT_AND_MOUSE_H_INCLUDED

enum Port {NONE=0, E=1<<0, N=1<<1, W=1<<2, S=1<<3};

class PortMask {
	int mask;
public:
	PortMask(int m) : mask(m) {}
	bool contains(Port p) { return (mask & p) != 0; }
	bool is_empty() { return mask==0; }
	PortMask remove(Port p) {
		if (!contains(p)) return PortMask(NONE);
		return PortMask(mask & ~p);
	}
	PortMask rotate(int dir) {
		while (dir<0) dir += 4;
		while (dir>3) dir -= 4;
		if (dir==0) return mask;
		return ((mask<<dir)&0x0F) | (mask>>(4-dir));
	}
};

class Piece {
public:
	virtual PortMask get_available_output_ports_mask(Port input_port) = 0;
	virtual void rotate(int dir) = 0;
	virtual void reset_availability() = 0;
	virtual void render() = 0;

protected:
	virtual void render_base();
};

struct Table {
	Piece *table[3][3];
	Piece **pieces;

	Piece **build_pieces();
	void dispose_pieces(Piece **p);

public:
	Table();
	~Table();

	void render();
};

#endif // CAT_AND_MOUSE_H_INCLUDED
